#ifndef PROXY_PING_CLIENT_H_
#define PROXY_PING_CLIENT_H_

#include "vzconn/base/basicdefines.h"
#include "vzconn/conn/tcpclient.h"
#include "database_server/database_server_defines.h"

namespace proxy{

  class PingClient : public boost::noncopyable,
    public boost::enable_shared_from_this< PingClient >{
  public:
    typedef boost::shared_ptr<PingClient> Ptr;

    typedef boost::function < void(PingClient::Ptr ping_client,
      const boost::system::error_code& err) > SignalPingErrorCallback;

    typedef boost::function < void(PingClient::Ptr ping_client) > 
      SignalPingSucceedCallbakc;

    typedef boost::function < void(PingClient::Ptr ping_client,
      const char* data, int size) > SignalOnlineServerListCallback;

    PingClient(boost::asio::io_service& io_service, int timeout);
    virtual ~PingClient();

    void SetSignalPingError(SignalPingErrorCallback callback){
      SignalPingError = callback;
    }

    void SetPingSucceedCallback(SignalPingSucceedCallbakc callback){
      SignalPingSucceed = callback;
    }

    void Start();
    void StartPingMessage();
    bool StartGetOnlineProxyServer(const char* user_name, int size,
      SignalOnlineServerListCallback callback);
  private:
    // With TcpClient
    void OnServerConnect(vzconn::TcpConnect::Ptr connect,
      const boost::system::error_code& err);

    // With Timeout Message
    void HandleTimeout(const boost::system::error_code& err);

    // With Tcp Connect
    void OnConnectError(vzconn::TcpConnect::Ptr connect,
      const boost::system::error_code& err);
    void OnConnectWrite(vzconn::TcpConnect::Ptr connect);
    void OnConnectRead(vzconn::TcpConnect::Ptr connect,
      const char* buffer, int size, int flag);

    // Register with the server
    void StartRegisterServer();
  private:
    boost::asio::io_service& io_service_;
    vzconn::TcpConnect::Ptr connect_;

    int timeout_;
    int ping_times_;
    boost::scoped_ptr<boost::asio::deadline_timer> timer_;
    SignalPingErrorCallback SignalPingError;
    SignalPingSucceedCallbakc SignalPingSucceed;
    SignalOnlineServerListCallback SignalOnlineServerList;
  };
}

#endif // PROXY_PING_CLIENT_H_